package com.chensi.admin.web.service.impl;

import com.chensi.admin.web.common.Constants;
import com.chensi.admin.web.domain.WebMenu;
import com.chensi.admin.web.dto.mapper.WebMenuMapper;
import com.chensi.admin.web.exception.BaseException;
import com.chensi.admin.web.exception.ItemRepeatException;
import com.chensi.admin.web.service.WebMenuService;
import com.chensi.admin.web.util.PageUtil;
import com.google.common.collect.Lists;
import com.chensi.admin.web.dao.WebMenuRepository;
import com.chensi.admin.web.dto.WebMenuDTO;
import com.chensi.admin.web.exception.ItemNotFoundException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @date 2019/6/20 14:09
 */

@Service
public class WebMenuServiceImpl implements WebMenuService {

    private final WebMenuRepository webMenuRepository;

    private final WebMenuMapper webMenuMapper;

    @Autowired
    public WebMenuServiceImpl(WebMenuRepository webMenuRepository, WebMenuMapper webMenuMapper) {
        this.webMenuRepository = webMenuRepository;
        this.webMenuMapper = webMenuMapper;
    }

    @Override
    public List<WebMenuDTO> list() {
        return webMenuRepository.findAll((root, query, cb) -> {
                    Predicate predicate = cb.equal(root.get("deleted"), Constants.DELETED_NO);
                    List<Predicate> predicates = Lists.newArrayList(predicate);
                    query.where(predicates.toArray(new Predicate[0]));
                    query.orderBy(cb.asc(root.get("sort")));
                    return query.getRestriction();
                }
        ).stream().map(webMenuMapper::toDTO).collect(Collectors.toList());
    }

    @Override
    public WebMenuDTO get(String id) throws BaseException {
        return webMenuMapper.toDTO(webMenuRepository.findById(id)
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("WebMenu [%s] not found", id))));
    }

    @Override
    public Page<WebMenuDTO> page(String name, Integer pageNum, Integer pageSize) {
        pageNum = PageUtil.pageNum(pageNum);
        pageSize = PageUtil.pageSize(pageSize);
        return webMenuRepository.findAll((root, query, cb) -> {
            Predicate p1 = cb.equal(root.get("deleted"), Constants.DELETED_NO);
            List<Predicate> predicates = Lists.newArrayList(p1);
            if (StringUtils.isNotBlank(name)) {
                predicates.add(cb.like(root.get("name"), "%" + name.trim() + "%"));
            }
            query.where(predicates.toArray(new Predicate[0]));
            return query.getRestriction();
        }, PageRequest.of(pageNum, pageSize))
                .map(webMenuMapper::toDTO);
    }

    @Override
    public WebMenuDTO create(WebMenu webMenu) throws BaseException {
        Optional<WebMenu> webMenuOptional = webMenuRepository.findByNameAndParentIdAndDeleted(
                webMenu.getName(), webMenu.getParentId(),
                Constants.DELETED_NO);
        if (webMenuOptional.isPresent()) {
            throw new ItemRepeatException(String.format("webMenu: %s is exist", webMenu.getName()));
        }
        webMenuRepository.save(webMenu);
        return webMenuMapper.toDTO(webMenu);
    }

    @Override
    public void update(WebMenu webMenu) throws BaseException {
        WebMenu old = webMenuRepository.findById(webMenu.getId())
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("WebMenu [%s] not found",
                        webMenu.getId())));
        if (old.getName().equals(webMenu.getName())) {
            throw new ItemNotFoundException(String.format("WebMenu [%s] is Exist",
                    webMenu.getName()));
        }
        webMenuMapper.update(old, webMenu);
        webMenuRepository.save(old);
    }

    @Override
    public void delete(String id) throws BaseException {
        //前置判断该菜单在中间表中是否被引用，如引用则删除中间表中角色的该菜单*/
        String menuId = webMenuRepository.queryMenuId(id);
        if (StringUtils.isNotBlank(menuId)) {
            webMenuRepository.delMenuId(menuId);
        }
        WebMenu webMenu = webMenuRepository.findById(id)
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("CmsTag [%s] not found", id)));
        webMenu.setDeleted(Constants.DELETED_YES);
        webMenuRepository.save(webMenu);
    }
}
